package com.sky.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.*;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.AddressMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.mapper.UserShopCartMapper;
import com.sky.properties.AddressProperties;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.utils.HttpClientUtil;
import com.sky.utils.WeChatPayUtil;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AddressMapper addressMapper;
    @Autowired
    private UserShopCartMapper userShopCartMapper;
    @Autowired
    private WeChatPayUtil weChatPayUtil;
    @Autowired
    private AddressProperties addressProperties;
    @Autowired
    private WebSocketServer webSocketServer;

    public JSONObject getAdminLngLat(){
        //https://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=您的ak&callback=showLocation
        Map<String, String> map = new HashMap<>();
        map.put("ak",addressProperties.getAk());
        map.put("address", addressProperties.getAddress());
        map.put("city", addressProperties.getCity());
        map.put("output", addressProperties.getOutput());
        String s = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3/?", map);
        log.info("-------------------------{}",s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        if((Integer) jsonObject.get("status") != 0){
            throw new OrderBusinessException("坐标获取失败！");
        }
        //result	object	返回的结果
        //location	object	经纬度坐标
        //lng	float	经度值
        //lat
        String string = jsonObject.get("result").toString();
        JSONObject jsonObject1 = JSONObject.parseObject(string);

        return jsonObject1;
    }
    public JSONObject getUserLngLat(AddressBook addressBook){
        //https://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=您的ak&callback=showLocation
        String detail = addressBook.getDetail();
        String cityName = addressBook.getCityName();
        Map<String, String> map = new HashMap<>();
        map.put("ak",addressProperties.getAk());
        map.put("address", detail);
        map.put("city", cityName);
        map.put("output", addressProperties.getOutput());
        String s = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3/?", map);
        log.info("-------------------------{}",s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        if((Integer) jsonObject.get("status") != 0){
            throw new OrderBusinessException("坐标获取失败！");
        }
        //result	object	返回的结果
        //location	object	经纬度坐标
        //lng	float	经度值
        //lat
        String string = jsonObject.get("result").toString();
        JSONObject jsonObject1 = JSONObject.parseObject(string);

        return jsonObject1;
    }

    public void getResult(JSONObject a,JSONObject u){
        //https://api.map.baidu.com/direction/v2/riding?origin=40.01116,116.339303&destination=39.936404,116.452562&ak=aakRny2CI4aR4ho6vv0Y7YQKRhDrdniG
        // origin=40.01116,116.339303&destination=39.936404,116.452562&ak=aakRny2CI4aR4ho6vv0Y7YQKRhDrdniG
        // https://api.map.baidu.com/direction/v2/riding?origin=118.549605,37.471234&destination=118.521472,37.470361&ak=aakRny2CI4aR4ho6vv0Y7YQKRhDrdniG
        // https://api.map.baidu.com/direction/v2/riding?origin=37.471234,118.549605&destination=37.470361,118.521472&ak=aakRny2CI4aR4ho6vv0Y7YQKRhDrdniG
        String aa = a.get("location").toString();
        String uu = u.get("location").toString();
        JSONObject aj = JSONObject.parseObject(aa);
        JSONObject uj = JSONObject.parseObject(uu);
        String alng = aj.get("lng").toString();
        String alat = aj.get("lat").toString();
        String ulng = uj.get("lng").toString();
        String ulat = uj.get("lat").toString();
        alng = alng.substring(0, alng.indexOf(".") + 7);
        alat = alat.substring(0, alat.indexOf(".") + 7);
        ulng = ulng.substring(0, ulng.indexOf(".") + 7);
        ulat = ulat.substring(0, ulat.indexOf(".") + 7);
        Map<String, String> map = new HashMap<>();
        map.put("origin",alat + "," +alng);
        map.put("destination",ulat + "," +ulng);
        map.put("ak",addressProperties.getAk());
        //TODO 经纬度可能搞反
        //map.put("riding_type","1");
        String s = HttpClientUtil.doGet("https://api.map.baidu.com/direction/v2/riding?", map);
        JSONObject jsonObject = JSONObject.parseObject(s);
        if((Integer) jsonObject.get("status") != 0){
            throw new OrderBusinessException("请求错误");
        }
        String result = jsonObject.get("result").toString();
        JSONObject jsonObject1 = JSONObject.parseObject(result);
        String routes = jsonObject1.get("routes").toString();
        JSONArray routesArray = JSONObject.parseArray(routes);
        // 遍历"routes"数组，这里以获取第一个元素为例
        String distance = null;
        if (!routesArray.isEmpty()) {
            JSONObject routeObject = routesArray.getJSONObject(0);

            // 直接从routeObject中获取"distance"
            distance = routeObject.getString("distance");

        }

        Float distance1 =Float.parseFloat(distance);
        if(distance1 > Float.parseFloat(addressProperties.getFar())){
            throw new OrderBusinessException("路线距离10km无法送达");
        }

    }
    /**
     * 用户下单
     * @param dto
     * @return
     */
    @Transactional
    @Override
    public OrderSubmitVO submit(OrdersSubmitDTO dto) {
        //获取收货人手机号
        AddressBook addressBook = addressMapper.getById(dto.getAddressBookId());
        //判断用户是否配送范围内
        JSONObject adminLngLat = getAdminLngLat();
        JSONObject userLngLat = getUserLngLat(addressBook);
        log.info("----------------------------------------{}",adminLngLat);
        log.info("----------------------------------------{}",userLngLat);
        //判断有没有超出距离
        getResult(adminLngLat, userLngLat);

        //获取用户id
        Long userId = BaseContext.getCurrentId();

        //获取用户名称
        User user = userMapper.getById(userId);
        //查询购物车
        List<ShoppingCart> list = userShopCartMapper.list(userId);
        //构造order表
        Orders orders = new Orders();
        BeanUtils.copyProperties(dto,orders);
        orders.setNumber(System.currentTimeMillis()+"");//设置订单编号
        orders.setStatus(1);//订单状态
        orders.setUserId(userId);//设置下单用户id
        orders.setOrderTime(LocalDateTime.now());//下单时间
        orders.setPayStatus(0);//支付状态
        orders.setPhone(addressBook.getPhone());//收件人手机号
        orders.setUserName(user.getName());//用户姓名
        orderMapper.insert(orders);
        //构造order_detail 表,把购物车里的数据转移到这张表
        Long id = orders.getId();
        List<OrderDetail> list1 = new ArrayList<>(list.size());
        list.forEach(i->{
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(i,orderDetail,"id");
            orderDetail.setOrderId(id);
            list1.add(orderDetail);
        });
        orderMapper.insertOrderDetail(list1);
        //删除购物车数据
        userShopCartMapper.delete(userId);
        //返回vo
        return OrderSubmitVO.builder()
                .id(id)
                .orderNumber(orders.getNumber())
                .orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime())
                .build();

    }

    /**
     * 订单支付
     *
     * @param ordersPaymentDTO
     * @return
     */
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
//        // 当前登录用户id
//        Long userId = BaseContext.getCurrentId();
//        User user = userMapper.getById(userId);
//
//        //调用微信支付接口，生成预支付交易单
//        JSONObject jsonObject = weChatPayUtil.pay(
//                ordersPaymentDTO.getOrderNumber(), //商户订单号
//                new BigDecimal(0.01), //支付金额，单位 元
//                "苍穹外卖订单", //商品描述
//                user.getOpenid() //微信用户的openid
//        );
//
//        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
//            throw new OrderBusinessException("该订单已支付");
//        }
//
//        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
//        vo.setPackageStr(jsonObject.getString("package"));

//        return vo;
        paySuccess(ordersPaymentDTO.getOrderNumber());
        return new OrderPaymentVO();
    }

    /**
     * 支付成功，修改订单状态
     *
     * @param outTradeNo
     */
    public void paySuccess(String outTradeNo) {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();

        // 根据订单号查询当前用户的订单
        Orders ordersDB = orderMapper.getByNumberAndUserId(outTradeNo, userId);

        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Orders orders = new Orders();
        orders.setId(ordersDB.getId());
        orders.setStatus(Orders.TO_BE_CONFIRMED);
        orders.setPayStatus(Orders.PAID);
        orders.setCheckoutTime(LocalDateTime.now());

        orderMapper.update(orders);

        //来单提醒
        Map map = new HashMap();
        map.put("type",1);
        map.put("orderId",ordersDB.getId());
        map.put("content","订单号：" + outTradeNo );
        String jsonString = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(jsonString);
    }

    /**
     * 查看历史订单
     * @param dto
     * @return
     */
    @Override
    public PageResult history(OrdersPageQueryDTO dto) {
        dto.setUserId(BaseContext.getCurrentId());
        PageHelper.startPage(dto.getPage(),dto.getPageSize());
        Page<OrderVO> page = orderMapper.history(dto);

        return new PageResult(page.getTotal(),page.getResult());
    }

    /**
     * 查询订单详情
     * @param id
     * @return
     */
    @Override
    public OrderVO order(Long id) {
        OrdersPageQueryDTO o = new OrdersPageQueryDTO();
        o.setId(id);
        PageHelper.startPage(1,10);
        Page<OrderVO> history = orderMapper.history(o);
        List<OrderVO> result = history.getResult();
        return result.get(0);
    }

    /**
     * 取消订单
     * @param id
     */
    @Override
    public void cancel(Long id) {
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelTime(LocalDateTime.now());
        orders.setUserId(BaseContext.getCurrentId());
        orderMapper.update(orders);
    }

    @Override
    @Transactional
    public void one(Long id) {
        //通过id查询的订单
        OrdersPageQueryDTO dto = new OrdersPageQueryDTO();
        dto.setId(id);
        PageHelper.startPage(1,1);
        Page<OrderVO> history = orderMapper.history(dto);
        List<OrderVO> result = history.getResult();
        OrderVO orderVO = result.get(0);
        //查询该订单下的所有商品,并放入购物车
        List<ShoppingCart> list = new ArrayList<>(orderVO.getOrderDetailList().size());
        orderVO.getOrderDetailList().forEach(i->{
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(i,shoppingCart,"id");
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCart.setUserId(BaseContext.getCurrentId());
            list.add(shoppingCart);
        });
        userShopCartMapper.insertBatch(list);


    }

    /**
     * 查询订单
     * @param dto
     * @return
     */
    @Override
    public PageResult page(OrdersPageQueryDTO dto) {

        PageHelper.startPage(dto.getPage(),dto.getPageSize());
        Page<Orders> page = orderMapper.page(dto);
        //查询地址等数据
        List<Orders> result = page.getResult();
        //TODO 优化
        result.forEach(i -> {
            User byId = userMapper.getById(i.getUserId());
            AddressBook byId1 = addressMapper.getById(i.getAddressBookId());
            i.setUserName(byId.getName());
            i.setAddress(byId1.getDistrictName() + '区' + byId1.getDetail());
        });
        return new PageResult(page.getTotal(),page.getResult());
    }

    /**
     * 接单
     * @param dto
     */
    @Override
    public void confirm(OrdersConfirmDTO dto) {

        //更新订单状态
        Orders orders = new Orders();
        orders.setId(dto.getId());
        orders.setStatus(Orders.CONFIRMED);
        orderMapper.update(orders);
    }

    /**
     * 拒单
     * @param dto
     */
    @Override
    public void rejection(OrdersRejectionDTO dto) {
        //更新订单状态
        Orders orders = new Orders();
        orders.setId(dto.getId());
        orders.setStatus(Orders.CANCELLED);
        orders.setRejectionReason(dto.getRejectionReason());
        orderMapper.update(orders);
    }

    /**
     * 取消订单
     * @param dto
     */
    @Override
    public void adminCancel(OrdersCancelDTO dto) {
        //查询订单
        Orders byId = orderMapper.getById(dto.getId());
        if(byId.getStatus() == 4 || byId.getStatus() == 5 || byId.getStatus() == 6){
            throw new OrderBusinessException("该订单已送出，无法取消");
        }
        //更新订单状态

        Orders orders = new Orders();
        orders.setId(dto.getId());
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelReason(dto.getCancelReason());
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.update(orders);
    }

    /**
     * 派送订单
     * @param id
     */
    @Override
    public void delivery(Long id) {
        //更新订单状态
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);

        orderMapper.update(orders);

    }

    /**
     * 完成订单
     * @param id
     */
    @Override
    public void complete(Long id) {
        //更新订单状态
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.COMPLETED);
        orders.setDeliveryTime(LocalDateTime.now());
        orderMapper.update(orders);
    }

    /**
     * 查看的提单详情
     * @param id
     * @return
     */
    @Override
    public OrderVO getOrderVo(Long id) {
        OrderVO orderVO = orderMapper.getOrderVo(id);
        return orderVO;
    }

    /**
     * 查看个订单状态
     * @return
     */
    @Override
    public OrderStatisticsVO status() {
        //查询订单状态
        OrderStatisticsVO vo = orderMapper.status();
        return vo;
    }

    /**
     * 客户催单
     * @param id
     */
    @Override
    public void reminder(Long id) {
        Orders orders = orderMapper.getById(id);

        if(orders == null){
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        Map map = new HashMap();
        map.put("type",2);
        map.put("orderId",id);
        map.put("content","客户催单了："+ orders.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));

    }
}
